package Demo3;

import java.util.concurrent.PriorityBlockingQueue;

class MyTask implements Comparable<MyTask>{
    public Runnable runnable;
    // 为了方便判定,使用绝对时间戳
    public long time;



    public MyTask(Runnable runnable,long delay) {
        this.runnable = runnable;
        // 表示当前时刻的时间戳+delay,作为该任务实际执行的时间戳
        this.time =System.currentTimeMillis() + delay;
    }

    @Override
    public int compareTo(MyTask o) {
        return (int)(this.time - o.time);
    }
}

class MyTimer {

    private PriorityBlockingQueue<MyTask> queue =
            new PriorityBlockingQueue<>();
    public Object locker = new Object();
    // 此处的delay表示的是多长时间之后执行任务
    public void schedule(Runnable runnable,long delay) {
        // 根据参数构造mytask,插入队列

        MyTask myTask = new MyTask(runnable,delay);
        queue.put(myTask);
        synchronized (locker) {
            locker.notify();
        }
    }
    // 创建线程,执行任务
    public MyTimer() {
        Thread t = new Thread(()-> {
           while(true) {
               try {
                   synchronized (locker) {
                       MyTask myTask = queue.take();
                       long curTime = System.currentTimeMillis();
                       if (myTask.time <= curTime) {
                           // 时间到了,可以执行时间了
                           myTask.runnable.run();
                       } else {
                           // 时间还没到 , 把刚才取出的任务重新塞回去,忙等,需要在等待过程中释放CPU
                           // 使用wait方法,阻塞等待,让出cpu
                           queue.put(myTask);
                           locker.wait(myTask.time - curTime);
                       }
                   }
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        t.start();
    }

}
public class ThreadDemo1 {
    public static void main(String[] args) {
        MyTimer myTimer = new MyTimer();
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("haha");
            }
        },1000);

        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("hahahha");
            }
        },2);
    }

}
